package top.hepingan.java.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import top.hepingan.java.common.Result;
import top.hepingan.java.dto.FrameLockDto;
import top.hepingan.java.entity.*;
import top.hepingan.java.mapper.*;
import top.hepingan.java.service.ForumService;
import top.hepingan.java.service.ShopService;
import top.hepingan.java.utils.AliUploadUtils;
import top.hepingan.java.utils.UserUtils;
import top.hepingan.java.vo.ForumVo;
import top.hepingan.java.vo.ShopVo;
import top.hepingan.java.vo.StatisticsVo;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@RequestMapping("/admin")
@RestController
@Slf4j
public class AdminController {

    private final UserMapper userMapper;
    private final ForumMapper forumMapper;
    private final ShopMapper shopMapper;
    private final ChatMapper chatMapper;
    private final ShopService shopService;
    private final ActivityMapper activityMapper;
    private final ForumService forumService;
    private final CarouselMapper carouselMapper;
    private final AliUploadUtils aliUploadUtils;
    private final ChatListMapper chatListMapper;
    private final ReportMapper reportMapper;
    private final FrameMapper frameMapper;
    private final FrameUnlockMapper frameUnlockMapper;

    @GetMapping("/user/page")
    public Result userPage(@RequestParam Integer pageNum,@RequestParam String keyword) {
        Page<User> p = new Page<>(pageNum,  10);
        if (keyword != null && !keyword.isEmpty()){
            return Result.data(userMapper.selectPage(p, new QueryWrapper<User>().lambda()
                    .like(User::getUsername, keyword)));
        }
        List<User> records = userMapper.selectPage(p, null).getRecords();
        return Result.data(records);
    }

    @GetMapping("/user/count")
    public Result userCount() {
        return Result.data(userMapper.selectCount(null));
    }

    @GetMapping("/statistics")
    public Result statistics() {
        Long userCount = userMapper.selectCount(null);
        LocalDateTime startOfDay = LocalDateTime.now().with(LocalTime.MIN);
        LocalDateTime endOfDay = LocalDateTime.now().with(LocalTime.MAX);
        Long todayPostCount = forumMapper.selectCount(new QueryWrapper<Forum>().lambda()
                .ge(Forum::getCreatedTime, startOfDay)
                .le(Forum::getCreatedTime, endOfDay));
        Long shopCount = shopMapper.selectCount(null);
        Long chatCount = chatMapper.selectCount(new QueryWrapper<Chat>().lambda()
                .ge(Chat::getCreatedTime, startOfDay)
                .le(Chat::getCreatedTime, endOfDay));
        StatisticsVo statisticsVo  = new StatisticsVo()
                .setChatCount(chatCount)
                .setForumCount(todayPostCount)
                .setShopCount(shopCount)
                .setUserCount(userCount);
        return Result.data(statisticsVo);
    }

    /**
     * 商家审核
     * @param pageNum
     * @param shopName
     * @param category
     * @return
     */
    @GetMapping("/shop/page")
    public Result shopPage(@RequestParam Integer pageNum, @RequestParam String shopName,@RequestParam String category) {
        List<ShopVo> shopVoList = shopService.pageBynum(pageNum, shopName, null, category,true,false);
        return Result.data(shopVoList);
    }

    /**
     * 管理审核
     * @param id
     * @return
     */
    @GetMapping("/shop/status")
    public Result shopStatus(@RequestParam Integer id,@RequestParam Integer status) {
        Shop shop = shopMapper.selectById(id);
        shop.setStatus(status);
        shopMapper.updateById(shop);
        return Result.ok();
    }

    @GetMapping("/shop/reason")
    public Result shopReason(@RequestParam Integer id,@RequestParam String reason) {
        Shop shop = shopMapper.selectById(id);
        shop.setReason(reason);
        shopMapper.updateById(shop);
        return Result.ok();
    }



    @GetMapping("/activity/page")
    public Result activityPage(@RequestParam Integer pageNum,@RequestParam String title,@RequestParam String type) {
        Page<Activity> p = new Page<>(pageNum,  10);
        QueryWrapper<Activity> activityQueryWrapper = new QueryWrapper<>();
        if (title != null && !title.isEmpty()){
            activityQueryWrapper.lambda().like(Activity::getTitle, title);
        }
        if (type != null && !type.isEmpty()){
            activityQueryWrapper.lambda().eq(Activity::getType, type);
        }
        return Result.data(activityMapper.selectPage(p,activityQueryWrapper).getRecords());
    }

    @PostMapping("/activity/add")
    public Result addActivity(@RequestBody Activity activity) {
        activity.setCreatedTime(LocalDateTime.now());
        activity.setUserId(UserUtils.getCurrentLoginId());
        activityMapper.insert(activity);
        return Result.ok();
    }

    @PostMapping("/activity/update")
    public Result update(@RequestBody Activity activity){
        return activityMapper.updateById(activity) > 0 ? Result.ok() : Result.error();
    }

    @PostMapping("/activity/delete")
    public Result update(@RequestBody Long id){
        aliUploadUtils.deleteFile(activityMapper.selectById(id).getImage());
        return activityMapper.deleteById(id) > 0 ? Result.ok() : Result.error();
    }

    @GetMapping("/forum/list")
    public Result forumList(@RequestParam Integer pageNum,@RequestParam String title) {
        List<ForumVo> forumVos = forumService.pageTotal(pageNum, title);
        return Result.data(forumVos);
    }

    @GetMapping("/forum/delete")
    public Result delete(@RequestParam Long id) {
        return forumMapper.deleteById(id) > 0 ? Result.ok() : Result.error();
    }

    @GetMapping("/forum/status")
    public Result status(@RequestParam Long id) {
        Forum forum = forumMapper.selectById(id);
        forum.setStatus(forum.getStatus() == 1 ? 0 : 1);
        return forumMapper.updateById(forum) > 0 ? Result.ok() : Result.error();
    }

    @PostMapping("/carousel/add")
    public Result addCarousel(@RequestBody Carousel carousel) {
        carousel.setCreatedTime(LocalDateTime.now());
        return carouselMapper.insert(carousel) > 0 ? Result.ok() : Result.error();
    }

    @GetMapping("/carousel/delete")
    public Result deleteCarousel(@RequestParam Long id) {
        return carouselMapper.deleteById(id) > 0 ? Result.ok() : Result.error();
    }

    @GetMapping("/message/list")
    public Result messageList(@RequestParam Integer pageNum) {
        Page<ChatList> p = new Page<>(pageNum,  10);
        return Result.data(chatListMapper.selectPage(p,null).getRecords());
    }

    @GetMapping("/report/list")
    public Result reportList(@RequestParam Integer pageNum,Integer status) {
        if (status != null){
            return Result.data(reportMapper.selectPage(new Page<>(pageNum,  10),new QueryWrapper<Report>().lambda().eq(Report::getStatus, status)).getRecords());
        }
        Page<Report> p = new Page<>(pageNum,  10);
        return Result.data(reportMapper.selectPage(p,null).getRecords());
    }

    @GetMapping("/report/status")
    public Result reportStatus(@RequestParam Long id) {
        Report report = reportMapper.selectById(id);
        report.setStatus(report.getStatus() == 1 ? 0 : 1);
        return reportMapper.updateById(report) > 0 ? Result.ok() : Result.error();
    }

    @GetMapping("/frame/list")
    public Result avatarList(@RequestParam Integer pageNum,@RequestParam String name) {
        Page<Frame> p = new Page<>(pageNum,  20);
        if (name != null && !name.isEmpty()){
            return Result.data(frameMapper.selectPage(p,new QueryWrapper<Frame>().lambda()
                    .like(Frame::getName, name)).getRecords());
        }else return Result.data(frameMapper.selectPage(p,null).getRecords());
    }

    @GetMapping("/frame/listAll")
    public Result frameListAll() {
        return Result.data(frameMapper.selectList(null));
    }

    @PostMapping("/frame/add")
    public Result addFrame(@RequestBody Frame frame) {
        frame.setCreatedTime(LocalDateTime.now());
        return frameMapper.insert(frame) > 0 ? Result.ok() : Result.error();
    }

    @PostMapping("/frame/unlock")
    public Result unlockFrame(@RequestBody FrameLockDto frameLockDto) {
        FrameUnlock frameUnlock = new FrameUnlock()
                .setFrameId(frameLockDto.getId())
                .setUserId(frameLockDto.getUserId())
                .setCreatedTime(LocalDateTime.now());
        return frameUnlockMapper.insert(frameUnlock) > 0 ? Result.ok() : Result.error();
    }

    @PostMapping("/frame/lock")
    public Result lockFrame(@RequestBody FrameLockDto frameLockDto) {
        return frameUnlockMapper.delete(new QueryWrapper<FrameUnlock>().lambda()
                .eq(FrameUnlock::getUserId, frameLockDto.getUserId())
                .eq(FrameUnlock::getFrameId, frameLockDto.getId())) > 0 ? Result.ok() : Result.error();
    }

    @GetMapping("/frame/lockList")
    public Result lockList(@RequestParam Long userId) {
        List<FrameUnlock> frameUnlocks = frameUnlockMapper.selectList(new QueryWrapper<FrameUnlock>().lambda()
                .eq(FrameUnlock::getUserId, userId));
        List<Long> frameIds = frameUnlocks.stream().map(FrameUnlock::getFrameId).collect(Collectors.toList());
        return Result.data(frameIds);
    }

    @GetMapping("/frame/detail")
    public Result frameDetail(@RequestParam Long id) {
        Frame frame = frameMapper.selectById(id);
        return Result.data(frame);
    }

    @PostMapping("/frame/update")
    public Result updateFrame(@RequestBody Frame frame) {
        return frameMapper.updateById(frame) > 0 ? Result.ok() : Result.error();
    }



}
